package com.questionnaires.controller;

import com.questionnaires.model.*;
import com.questionnaires.service.QuestionService;
import com.questionnaires.service.QuestionnaireService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author ioana.ruca@gmail.com
 */
@Controller
public class QuestionController {

    @Autowired
    QuestionService questionService;

    @Autowired
    QuestionnaireService questionnaireService;

    public static final String EMPTY_RESPONSE_ERR_KEY = "NotBlank.question.response";

    public static final String ERROR_MESSAGE_PARAM_NAME = "errorMessage";

    /**
     * Create question view.
     */
    public static final String CREATE_QUESTION_VIEW = "question/addQuestion";

    public static final String VIEW_SAVED_QUESTIONS = "questionnaire/savedQuestions";

    /**
     * Creates questionnaire content view.
     */
    public static final String VIEW_Q_CONTENT = "public_user/get_q_content";


    /**
     * Returns the create question view.
     *
     * @param modelMap
     * @return
     */
    @RequestMapping(value = "/addQuestion", method = RequestMethod.GET)
    public String viewCreateQuestion(Map<String, Object> modelMap, HttpSession session) {

        User user = (User)session.getAttribute("user");
        if (user == null || !user.checkUserManager() )
            return UserController.REDIRECT_INDEX;
        Question question = new Question();
        List<Response> responses = new ArrayList<Response>();
        for (int i = 0; i < 3; i++) {
            Response response = new Response();
            response.setId(i);
            responses.add(response);
        }
        question.setResponseType(QuestionResponseType.SINGLE);
        question.setResponses(responses);
        modelMap.put("question", question);
        return CREATE_QUESTION_VIEW;
    }

    /**
     * Validates the responses for question.
     *
     * @param responses
     * @param declaredNoOfResponses
     * @return
     */
    private boolean validateResponses(List<Response> responses, int declaredNoOfResponses) {

        if (declaredNoOfResponses != responses.size()) {
            return false;
        }
        for (Iterator iterator = responses.iterator(); iterator.hasNext(); ) {
            Response response = (Response) iterator.next();
            if (response.getText().equals("")) {
                return false;
            }
        }
        return true;
    }

    /**
     * Adds a new completed question to the questionnaire whose id is saved on the sesssion.
     *
     * @param modelMap
     * @param question
     * @param result
     * @param request
     * @param session
     * @return the add question view with errors displayed if the validation was unsuccessful or null otherwise
     */
    @RequestMapping(value = "/questions/add", method = RequestMethod.POST)
    public String addQuestion(Map<String, Object> modelMap, @ModelAttribute("question")
    @Valid Question question, BindingResult result, HttpServletRequest request,
                              HttpSession session) {

        User user = (User)session.getAttribute("user");
        if (user == null || !user.checkUserManager() )
            return UserController.REDIRECT_INDEX;
        if (result.hasErrors()) {
            return CREATE_QUESTION_VIEW;
        }
        if (!validateResponses(question.getResponses(), Integer.parseInt(request.getParameter("noOfResponses")))) {
            modelMap.put(ERROR_MESSAGE_PARAM_NAME, EMPTY_RESPONSE_ERR_KEY);
            return CREATE_QUESTION_VIEW;
        }
        Questionnaire questionnaire = questionnaireService.findById(
                (Long) session.getAttribute(QuestionnaireController.ID_QUESTIONNAIRE_SESSION_ATTR));
        List<Question> questions = questionnaire.getQuestions();
        if (questions == null) {
            questions = new ArrayList<Question>();
        }
        questions.add(question);
        questionnaire.setQuestions(questions);

        questionnaireService.saveOrUpdate(questionnaire);

        return null;
    }

    /**
     * Retrieves the already saved questions for the questionnaire id on session and returns the savedQuestions view
     */
    @RequestMapping(value = "addQuestionnaire/savedQuestions", method = RequestMethod.GET)
    public String viewSavedQuestionsOnQCreate(Map<String, Object> modelMap, HttpSession session) {

        User user = (User)session.getAttribute("user");
        if (user == null || !user.checkUserManager() )
            return UserController.REDIRECT_INDEX;
        Questionnaire questionnaire = questionnaireService.findById(
                (Long) session.getAttribute(QuestionnaireController.ID_QUESTIONNAIRE_SESSION_ATTR));
        modelMap.put("questionsList", questionnaire.getQuestions());

        return VIEW_SAVED_QUESTIONS;
    }

    @RequestMapping(value = "/getQContent")
    public String getQuestionnaireContent(HttpServletRequest request, Map<String, Object> map) {

        Questionnaire questionnaire = questionnaireService.findById(Long.parseLong((request.getParameter("q_id"))));
        map.put("questionsList", questionnaire.getQuestions());

        Questionnaire newQuestionnaire = new Questionnaire();
        List<Question> newQuestions = new ArrayList<Question>();

        for (int i = 0; i < questionnaire.getQuestions().size(); i++) {
            Question newQ = new Question();
            newQ.setResponses(new ArrayList<Response>());
            newQuestions.add(newQ);
        }
        newQuestionnaire.setQuestions(newQuestions);
        map.put("questionnaire", newQuestionnaire);
        map.put("id", questionnaire.getId());
        return VIEW_Q_CONTENT;

    }

}
